package models;

import play.*;
import play.data.binding.As;
import play.data.validation.Required;
import play.db.jpa.*;
import play.modules.search.*;

import javax.persistence.*;

import java.util.*;

@Indexed
@Entity
public class Question extends Model {
    
	@As("yyyy-MM-dd")
	public Date postedAt;
	
	@Field
	@Required
	public String content;
	
	@ManyToOne
	public User postedBy;
	
	@ManyToOne
	public Lecture lecture;
	
	@Field
	@Required
	public String title;
	
	@ManyToMany(mappedBy="votedFor", cascade=CascadeType.PERSIST)
	public Set<User> voters;
	
	public boolean answered;
	
	@OneToMany(mappedBy="question", cascade=CascadeType.ALL)
	public List<Answer> answers;
	
	@OneToMany(mappedBy="question", cascade=CascadeType.ALL)
	public List<Comment> comments;
	
	//constructor
	public Question(User postedBy, Lecture lecture, String title, String content) {
		this.lecture = lecture;
		this.postedBy = postedBy;
		this.title = title;
		this.content = content;
		this.postedAt = new Date();
		this.answered = false;
		create();
	}
	
	public int votes() {
		return voters.size();
	}
	
	//Answer handlers
	
	/**
	 * Answer a Question
	 */
	public Answer answer(User postedBy, String title, String content) {
		this.answered = true;
		this.save();
		return new Answer(this, postedBy, title, content);
	}
	
	//Different Comment handlers
	
	/**
	 * Comment on a Question
	 */
	public Comment comment(User by, String content) {
		return new Comment(this, by, content);
	}
	
	/**
	 * Find all Comments for this lecture
	 */
	public List<Comment> getComments() {
        return Comment.find("question", this).fetch();
    }
	
	public Long getCommentCount() {
		return Comment.count("question", this);
	}
	
	/**
	 * Count how many different users commented
	 */
	public Long getVoicesCount() {
        return User.count("select count(distinct u) from User u, Question q, Comment c where c.postedBy = u and c.question = q and q = ?", this);
    }
	
	public Comment getLastComment() {
		return Comment.find("question = ? order by postedAt desc", this).first();
	}
}
